﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pavilion.DesignerTool.ViewTools;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows;

namespace Pavilion.DesignerTool
{
    public class LockWrapper : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public ILock Lock { get; set; }
        public LinkWrapper LinkWrapperParent { get; private set; }
        public PropertyCategory PropertyCategory { get; private set; }

        public IEnumerable<GameItemWrapper> GameItemCollection { get { return GameItemWrapperManager.GameItemWrapperCollection; } }
        public string SelectedGameItemDisplayName { get { return "GameItem: " + GameItemWrapperManager.GetGameItemWrapper(Lock.GameItemName).Name; } }

        public LockWrapper(ILock lockItem, LinkWrapper parent)
        {
            this.Lock = lockItem;
            this.LinkWrapperParent = parent;

            IEnumerable<LockPropertyItem> lockPropertyList = LockPropertyItem.GetLockProperties(lockItem, this);
            PropertyCategory = new PropertyCategory(this);

            foreach (LockPropertyItem propertyItem in lockPropertyList)
            {
                PropertyCategory.AddProperty(propertyItem);
                propertyItem.CanTransferUpdate = true; 
            }
        }

        public override string ToString()
        {
            return Lock.ToString();
        }

        public void SetGameItemName(string gameItemName)
        {
            Lock.GameItemName = gameItemName;

            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(Lock))
            {
                if (descriptor.DisplayName == "GameItemName")
                    LockTransfer.Update(this, descriptor);
            }

            OnPropertyChanged("SelectedGameItemDisplayName");
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class LockPropertyItem : ObjectPropertyItem
    {
        public event Action<LockPropertyItem> PropertyChanged;

        public bool CanTransferUpdate { get; set; }
        public LockWrapper LockWrapperParent { get; private set; }

        public LockPropertyItem(ILock lockItem, LockWrapper parent, PropertyDescriptor propertyDescriptor) : base(propertyDescriptor, lockItem)
        {
            this.LockWrapperParent = parent;
        }

        protected override void LoadDefaultFrameworkElement()
        {
            if (PropertyName == "FocusGameItem")
            {
                string gameItemName = (PropertyValue == null) ? null : PropertyValue.ToString();

                LoadComboBox(this, GameItemWrapperManager.GetGameItemWrapper(gameItemName), GameItemWrapperManager.GameItemWrapperCollection,
                    (sender, e) =>
                    {
                        if ((sender as ComboBox).SelectedItem != null)
                            PropertyValue = ((sender as ComboBox).SelectedItem as GameItemWrapper).GameItem;
                        else
                            PropertyValue = null;
                    });
            }
            else
            {
                base.LoadDefaultFrameworkElement();

            }
        }

        static public IEnumerable<LockPropertyItem> GetLockProperties(ILock lockItem, LockWrapper lockWrapper)
        {
            List<LockPropertyItem> lockPropertyList = new List<LockPropertyItem>();
            PropertyDescriptorCollection propertyDescriptors = TypeDescriptor.GetProperties(lockItem);

            foreach (PropertyDescriptor descriptor in propertyDescriptors)
            {
                if (descriptor.DisplayName != "GameItemName")
                    lockPropertyList.Add(new LockPropertyItem(lockItem, lockWrapper, descriptor));
            }

            return lockPropertyList;
        }

        static public Dictionary<string, object> GetLockProperties(ILock lockItem)
        {
            Dictionary<string, object> propertyList = new Dictionary<string,object>();
            PropertyDescriptorCollection propertyDescriptors = TypeDescriptor.GetProperties(lockItem);

            foreach (PropertyDescriptor descriptor in propertyDescriptors)
                propertyList.Add(descriptor.DisplayName, descriptor.GetValue(lockItem));

            return propertyList;
        }

        private void UpdateLockData()
        {
            if (CanTransferUpdate)
                LockTransfer.Update(this);
        }

        protected override void SetPropertyValue(object value)
        {
            if (PropertyValue == value)
                return;

            base.SetPropertyValue(value);
            OnPropertyChanged();

            UpdateLockData();
        }

        private void OnPropertyChanged()
        {
            if (PropertyChanged != null)
                PropertyChanged(this);
        }
    }
}
